package config

import (
	"log"
	"os"
	"time"

	"github.com/spf13/viper"
)

var TikTok Config

type (
	Config struct {
		server
		app
		jwt
		dataSource
		oss
	}

	// server Http服务配置
	server struct {
		RunMode      string        // RunMode 运行模式
		HTTPPort     string        // HTTPPort 服务端口号
		ReadTimeout  time.Duration // ReadTimeout 读取超时时间
		WriteTimeout time.Duration // WriteTimeout 写入超时时间
	}

	// app 应用配置
	app struct {
		DefaultPageSize       uint32        // DefaultPageSize 默认分页大小
		MaxPageSize           uint32        // MaxPageSize 每页最大大小
		DefaultContextTimeout time.Duration // DefaultContextTimeout 默认上下文超时时间
		// 日志配置
		Log struct {
			SavePath   string // SavePath 日志保存地址
			FileName   string // FileName 日志文件名称
			FileExt    string // FileExt 日志文件扩展名
			MaxSize    int    // MaxSize 日志切割文件的最大大小
			MaxBackUps int    // MaxBackUps 保留旧文件的最大个数
			MaxAge     int    // MaxAge 保留旧文件的最大天数
		}
	}

	// jwt JWT验证配置
	jwt struct {
		Secret     string        // Secret JWT 密钥
		Issuer     string        // Issuer JWT 发行
		Timeout    time.Duration // Timeout 过期时间
		MaxRefresh time.Duration // MaxRefresh 最大刷新时间
	}

	// dataSource 数据库结构体
	dataSource struct {
		// MySQL Mysql配置
		MySQL struct {
			Host        string // Host 主机地址
			UserName    string // UserName 用户名称
			Password    string // Password 用户密码
			DBType      string // DBType 数据库类型
			DBName      string // DBName 数据库名臣
			MaxOpenConn int    // MaxOpenConn 最大打开连接
			MaxIdleConn int    // MaxIdleConn 最大闲置连接
			Charset     string // Charset 字符集
			ParseTime   string // ParseTime 是否将数据库时间类型转换成Go时间类
			TimeLocal   string // TimeLocal 时间区域
		}
		// Redis redis配置
		Redis struct {
			Addr     string // Addr redis服务地址
			Password string // Password redis密码
			DBIndex  int    // DBIndex 数据库下标
		}
	}

	oss struct {
		AccessKey string
		SecretKey string
		URL       string
	}
)

func Init() {
	path := os.Getenv("CONFIG_PATH")
	vp := viper.New()
	vp.SetConfigType("yaml")
	vp.SetConfigName("config")
	vp.AddConfigPath(path)
	if err := vp.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			log.Fatalf("no such config file: %v\n", err)
		} else {
			log.Fatalf("read config error: %v\n", err)
		}
	}

	if err := vp.UnmarshalKey("dataSource", &TikTok.dataSource); err != nil {
		log.Fatalf("读取配置文件失败:%v\n", err)
	}

	if err := vp.UnmarshalKey("app", &TikTok.app); err != nil {
		log.Fatalf("读取配置文件失败:%v\n", err)
	}

	if err := vp.UnmarshalKey("server", &TikTok.server); err != nil {
		log.Fatalf("读取配置文件失败:%v\n", err)
	}
	TikTok.server.ReadTimeout *= time.Second
	TikTok.server.WriteTimeout *= time.Second

	if err := vp.UnmarshalKey("auth", &TikTok.jwt); err != nil {
		log.Fatalf("读取配置文件失败:%v\n", err)
	}
	TikTok.Timeout *= time.Minute
	TikTok.MaxRefresh *= time.Minute

	if err := vp.UnmarshalKey("oss", &TikTok.oss); err != nil {
		log.Fatalf("读取配置文件失败:%v\n", err)
	}

	if err := vp.UnmarshalKey("jwt", &TikTok.jwt); err != nil {
		log.Fatalf("读取配置文件失败:%v\n", err)
	}
	TikTok.Timeout *= time.Hour
	TikTok.MaxRefresh *= time.Hour
}
